﻿#! /usr/bin/env python
# -*- coding: utf-8 -*-

import time
import os
import json
import hashlib
import StringIO

import FileHostProtoType
from ..utility.gadget import cutstr

class u115item(FileHostProtoType.HostItem):
    pass

class u115(FileHostProtoType.FileHostProcess):   
    HOST_URL = "http://115.com/"
    LOGIN_URL = "https://passport.115.com/?ac=login" 
    ACCOUNT_URL = "http://my.115.com/?ct=account&ac=update_user_info"
    SPACE_URL = "http://115.com/api/open/space.php?js_return=mySpace&_=%s"
    DOWNLOAD_URL = "http://u.115.com/file/%s"
    SHARE_URL = "http://115.com/?ct=file&ac=one_key_share"
    SEC_TRAN_URL = "http://lb.u.115.com/api/index.php"
    CONTINUOUS_URL = "http://58.253.94.227/ups/up?sha1=%s&filename=%s&filesize=%s&key=%s&version=%s" 
             
    def __init__(self, user, pwd):
        FileHostProtoType.FileHostProcess.__init__(self)
        self.hostname = "u.115.com" 
        self._opener = None
        self._user = user
        self._pwd = pwd
        self.islogin = False
        self.logtype = 'poster'
        self._cookieCurl = self._user + '_%s.cookie' % self.hostname
        self._cookieCurl = os.path.join(os.path.dirname(__file__), self._cookieCurl)
                
    def login(self):        
        self.generateOpener()
        if self.restore_cookiejar():
            return True
        self.fherr.write('login to %s %s/%s...' % (self.hostname, self._user,'*'*len(self._pwd)))
        loginData = {'login[account]' : self._user, 
                     'login[passwd]' : self._pwd
                     }
        loginresult =  self.loginFileHost(
                    self.LOGIN_URL, 
                    loginData
                    )
        account_info = self.post_request(self.ACCOUNT_URL)
        # you always see you username at the top of the page, if login successfully.
        if self._user.lower() not in account_info.lower():
            self.fherr.write("User %s Failed to Login MegaUpload." % self._user)
            return False
        self.fherr.write("User %s logined." % self._user)
        self._cj.save(self._cookieCurl, ignore_discard=True)
        self.islogin = True
        return True
    
    def restore_cookiejar(self):
        '''
        load cookie file, then access website to verify if cookie is avaiable
        '''
        if os.path.isfile(self._cookieCurl):
            self.fherr.write('Restore Local Cookie.')
            try:
                self._cj.load(self._cookieCurl, ignore_discard=True)
            except:
                self.fherr.write('Failed to Restore Local CookieJar.')
            #access website to conferm cookie is avaiable
            return self.check_cookie()
        return False  

    def check_cookie(self):
        self.fherr.write('Checking Cookie...')
        response = self.post_request(self.ACCOUNT_URL)
        if response and self._user in response:
            self.fherr.write("User %s Status : Logined." % self._user)
            self.islogin = True             
            return True
        self.fherr.write("[%s]User %s Status : not Logined." % (time.ctime(), self._user))
        self.fherr.write(response)
        return False
    
    def get_upload_url(self, page):
        upload_url = self.get_upload_key(page, 'upload_url', 1, '"upload_url":"')
        upload_url = upload_url[:upload_url.find('"')]
        return upload_url.replace('\/','/')
    
    def upload_web(self, file, progressLog=None, other_args=None, send_range=None):
        callback = None
        if progressLog is not None:
            callback = progressLog.write
            
        data ={}
        indexpage = self.post_request(self.HOST_URL)
        
        
        data['cookie'] = self.get_upload_key(indexpage, 'USER_COOKIE =', -2, "'")
        data['token'] = self.get_random().lower()
        data['aid'] = '1'
        data['time'] = self.get_timeticket()
        data['Upload'] = 'Submit Query'
        
        upload_link = self.get_upload_url(indexpage)
                            
        filesize = os.path.getsize(file)
        filename = self.rename_func(file)
        start_point = 0
        info = "Uploading...%s" % file
        if send_range is not None:
            #range is a 3-tuple, <start, end, number>
            filesize = send_range[1] - send_range[0] + 1
            filename += ".%03d" % send_range[2]
            start_point = send_range[0]
            info += " part%d" % send_range[2]
        
        fileobj = open(file, 'rb')
        fileobj.seek(start_point) 
        data['Filedata'] = fileobj
        data['Filename'] = filename

#        hash transfer                #
#        sec_tran_data = {}
#        sec_tran_data['cmd'] = 'upload'
#        sec_tran_data['cookie'] = self.get_upload_key(indexpage, 'USER_COOKIE_LB', -2, "'")
#        sec_tran_data['user_id'] = self.get_upload_key(indexpage, 'USER_ID', -2, "'")
#        sec_tran_data['sha1'] = self.file_sha1(fileobj, filesize)
#        sec_tran_data['aid'] = '1' 
#        sec_tran_data['filesize'] = filesize
#        sec_tran_data['filename'] = filename 
#        sec_tran_data['cid'] = '0'
#        sec_tran_data['pick_code'] = ''
#        sec_tran_data['isp'] = '0'
#        sec_tran_data['isweb'] = '1'
#        # var PAGE_UPLOAD_OCX_VERSION = {WIN: "v1.7.1.2", MAC:"v1.5.7.0", UNIX: "v1.5.7.0"};
#        sec_tran_data['version'] = self.get_upload_key(indexpage, 'PAGE_UPLOAD_OCX_VERSION', -6, '"')
#        sec_tran_data['md115'] = '' 
#        print sec_tran_data['md115']
#        result = self.post_request(self.SEC_TRAN_URL, sec_tran_data)
#        print "find result:", result
#        if "pickcode" in result:
#            is_need_upload = cutstr(result, '<is_need_upload>', '</is_need_upload>')
#            file_code = cutstr(result, '<pickcode>', '</pickcode>')
#            if is_need_upload == '1':
#                ups_sha1 = cutstr(result, '<ups_sha1>', '</ups_sha1>')
#                key = cutstr(result, '<key>', '</key>')
#                continuous_upload_data = {}
#                continuous_upload_data['U_BlockSchema'] = '0'
#                continuous_upload_data['U_offset'] = '0'
#                continuous_upload_data['Filedata'] = fileobj
#                
#                upload_url = self.CONTINUOUS_URL % (ups_sha1, file_code, sec_tran_data['filesize'], key, sec_tran_data['version'])
#                print continuous_upload_data
#                print upload_url
#                result = self.post_request(upload_url, continuous_upload_data, retry=1, cb=callback, setfilename=file_code, setfilesize=filesize)
#                print "c-upload result:\n",  result
#            filelink = self.DOWNLOAD_URL % file_code + "#" + filename
#            file_page = self.post_request(filelink)
#            file_id = self.get_upload_key(file_page, 'file_id', -2, "'")
#            item = u115item(os.path.basename(file), 'file', file_id, filelink, filename)
#            self.share_file([item,])
#            self.newupload.append(item)
#            self.fhout.write(item.format()) 
#            return item
            
#        print data
        self.fherr.write(info)        
        
        result = self.post_request(upload_link, data, retry=1, cb=callback, setfilename=filename, setfilesize=filesize)
        #result#
#        print result
        if '"state":1' in result:
            resp = json.loads(result)
            
            file_code = resp['data']['pick_code']
            file_id = resp['data']['file_id']
            filelink = self.DOWNLOAD_URL % file_code + "#" + filename
            item = u115item(os.path.basename(file), 'file', str(file_id), filelink, filename)
            self.share_file([item,])
            self.newupload.append(item)
            self.fhout.write(item.format()) 
            return item
        
        self.fherr.write("Failed to upload?")
        self.fherr.write(result)
        
    def share_file(self, file_items):
        if not file_items:
            self.fherr.write("no file to share.")
        data = {}
        data['tid'] = ','.join([item.id for item in file_items])
        data['aid'] = '1'
        data['pid'] = '0'
        data['is_collect'] = '1'
        data['is_share'] = '1'
        
        response = self.post_request(self.SHARE_URL, data)
        if '"state":1' in response:
            self.fherr.write("Shared!")
        else:
            self.fherr.write("Error happened when shareing")
            self.fherr.write(response)
    
    def file_sha1(self, fileobj, filesize):
        start_point = fileobj.tell()
        
        BLOCK_SIZE = 10 << 20
        m = hashlib.sha1()
        
        need = filesize
        while need > 0:
            size_this_time = min(BLOCK_SIZE, need)
            data = fileobj.read(size_this_time) 
            m.update(data)
            need -= size_this_time
            
        fileobj.seek(start_point) 
        
        return m.hexdigest().upper()